package com.supreme.cacheserver.controller;

import com.supreme.cacheserver.service.RedissonService;
import com.supreme.cacheserver.utils.RedissonLock;
import com.supreme.commonboot.utils.AjaxResp;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(value = "redisson")
public class RedissonController {

    @Resource
    private ThreadPoolTaskExecutor supremeTaskExecutor;

    @Resource
    private RedissonLock redissonLock;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedissonService redissonService;

    @GetMapping(value = "testRedisson")
    public AjaxResp testRedisson() {
        RLock tttSss = redissonClient.getLock("TTT_SSS");
        tttSss.lock();
        System.out.println("tttSss = " + tttSss);
        tttSss.unlock();
        return AjaxResp.instance();
    }

    @GetMapping(value = "test/{duration}")
    public AjaxResp redissonTest(@PathVariable(value = "duration") Long duration) {
        redissonLock.lock("lockTest");
        final LocalDateTime localDateTime = LocalDateTime.now();
        final String dateStr = localDateTime.toString();
        System.out.println("lockTest start: " + dateStr);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("lockTest finish: " + dateStr);
        redissonLock.unlock("lockTest");
        return AjaxResp.instance();
    }

    @GetMapping(value = "testRedissonLock/{key}")
    public AjaxResp testRedissonLock(@PathVariable(value = "key") String key) {
        CompletableFuture.runAsync(() -> redissonService.testRedissonLock(key), supremeTaskExecutor);
        return AjaxResp.instance();
    }

    @GetMapping(value = "testRedissonTryLock/{key}")
    public AjaxResp testRedissonTryLock(@PathVariable(value = "key") String key) {
        CompletableFuture.runAsync(() -> redissonService.testRedissonTryLock(key), supremeTaskExecutor);
        return AjaxResp.instance();
    }

    @GetMapping(value = "testRedissonTryLockTimeout/{key}")
    public AjaxResp testRedissonTryLockTimeout(@PathVariable(value = "key") String key) {
        CompletableFuture.runAsync(() -> redissonService.testRedissonTryLockTimeout(key), supremeTaskExecutor);
        return AjaxResp.instance();
    }

    @GetMapping(value = "lockCode/{code}")
    public AjaxResp lockCode(@PathVariable(value = "code") String code) {
        CompletableFuture.runAsync(() -> redissonService.lockCode(code));
        return AjaxResp.instance();
    }

    @GetMapping(value = "testRedissonAnnoDummy/{code}")
    public AjaxResp testRedissonAnnoDummy(@PathVariable(value = "code") String code) {
        CompletableFuture.runAsync(() -> redissonService.testRedissonAnnoDummy(code));
        return AjaxResp.instance();
    }

    @GetMapping(value = "redisLockForCode/{code}")
    public AjaxResp testRedissonAnno(@PathVariable(value = "code") String code) {
        CompletableFuture.runAsync(() -> redissonService.redisLockForCode(code, 999, "你好世界"));
        return AjaxResp.instance();
    }

    @GetMapping(value = "redisLockForAnno/{code}")
    public AjaxResp redisLockForAnno(@PathVariable(value = "code") String code) {
        CompletableFuture.runAsync(() -> redissonService.redisLockForAnno(code, 888, "你好世界"));
        return AjaxResp.instance();
    }
}
